#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
#include <sw/redis++/redis++.h>
#include <chrono>
#include <thread>
#include "util.hpp"

using namespace std::chrono_literals;

void test1(sw::redis::Redis& redis)
{
    std::cout << "get 和 set 的使用" << std::endl;
    //清空一下数据库，避免之前残留的数据有干扰
    redis.flushall();

    redis.set("key1", "111");
    auto result  = redis.get("key1");
    std::cout << "value = " << result.value() << std::endl;

    redis.set("key1","123");
    result = redis.get("key1");
    std::cout << "value = " << result.value() << std::endl;
}

void test2(sw::redis::Redis& redis)
{
    std::cout << "set NX 和 XX" << std::endl;

    //清空一下数据库，避免之前残留的数据有干扰
    redis.flushall();

    redis.set("key1", "111", std::chrono::seconds(10));
    std::this_thread::sleep_for(std::chrono::seconds(5));
    long long time = redis.ttl("key1");
    std::cout << time << std::endl;
}

void test3(sw::redis::Redis& redis)
{
    std::cout << "set NX 和 XX" << std::endl;
    //清空一下数据库，避免之前残留的数据有干扰
    redis.flushall();
    redis.set("key1", "111");
    //set 的重载版本中没有单独提供 NX 和 XX 的版本，必须搭配过期版本来使用！
    redis.set("key1", "123", 0s, sw::redis::UpdateType::NOT_EXIST);
    auto value = redis.get("key1");
    if(value)
    {
        std::cout << "value = " << value.value() << std::endl;
    }
    else
    {
        std::cout << "key 不存在" << std::endl;
    }
}

void test4(sw::redis::Redis& redis)
{
    std::cout << "mset 的使用" << std::endl;
    //清空一下数据库，避免之前残留的数据有干扰
    redis.flushall();
    redis.mset({std::make_pair("key1", "111") ,std::make_pair("key2", "222"), std::make_pair("key3", "333")});
    std::vector<std::pair<std::string, std::string>> keys = {
        {"key4", "444"},
        {"key5", "555"},
        {"key6", "666"}
    };
    redis.mset(keys.begin(), keys.end());
    auto value = redis.get("key1");
    if(value){
        std::cout << value.value() <<std::endl;
    }
    value = redis.get("key2");
    if(value){
        std::cout << value.value() <<std::endl;
    }
    value = redis.get("key3");
    if(value){
        std::cout << value.value() <<std::endl;
    }
}

void test5(sw::redis::Redis& redis)
{
    std::cout << "mget 的使用" << std::endl;
    //清空一下数据库，避免之前残留的数据有干扰
    redis.flushall();
        std::vector<std::pair<std::string, std::string>> keys = {
        {"key4", "444"},
        {"key5", "555"},
        {"key6", "666"}
    };
    redis.mset(keys.begin(), keys.end());
    std::vector<sw::redis::OptionalString> result;
    auto it = std::back_inserter(result);
    redis.mget({"key4", "key5", "key6","key"}, it);
    printContainerOptional(result);
}

void test6(sw::redis::Redis& redis)
{
    std::cout << "getrange 和 setrange 的使用" << std::endl;
    //清空一下数据库，避免之前残留的数据有干扰
    redis.flushall();
    redis.set("key", "adcdefghijk");
    std::string result = redis.getrange("key", 2, 5);
    std::cout << "result: " << result <<std::endl;
    redis.setrange("key", 2, "xyz");
    auto value =  redis.get("key");
    std::cout << "value = " << value.value() << std::endl;
}

void test7(sw::redis::Redis& redis)
{
    std::cout << "incr 和 decr 的使用" << std::endl;
    //清空一下数据库，避免之前残留的数据有干扰
    redis.flushall();
    redis.set("key", "100");
    long long result = redis.incr("key");
    std::cout << "result: " << result <<std::endl;
    auto value =  redis.get("key");
    std::cout << "value = " << value.value() << std::endl;

    result = redis.decr("key");
    std::cout << "result: " << result <<std::endl;
    value =  redis.get("key");
    std::cout << "value = " << value.value() << std::endl;
}

int main(int argc, char *argv[])
{
    sw::redis::Redis redis("tcp://127.0.0.1:6379");
    // test1(redis);
    // test2(redis);
    // test3(redis);
    // test4(redis);
    // test5(redis);
    // test6(redis);
    test7(redis);
    return 0;
}